<template>
    <basic-container>
        <avue-crud v-bind="bindVal"
                   v-on="onEvent"
                   v-model="form"
                   v-permission="{addBtn: 'SYSTEM_ROLE_ADD',editBtn: 'SYSTEM_ROLE_UPDATE',delBtn: 'SYSTEM_ROLE_DELETE'}"
                   :before-open="beforeOpen"
                   ref="crud">

            <template slot="menuLeft" slot-scope="{size}">
                <el-button type="danger"
                           v-permission="'SYSTEM_ROLE_DELETE'"
                           icon="el-icon-delete"
                           :size="size"
                           @click.stop="deletes()">批量删除
                </el-button>
            </template>

            <template slot="menuBtn"
                      slot-scope="scope">

                <el-dropdown-item divided
                                  icon="el-icon-user"
                                  v-permission="'SYSTEM_ROLE_USER'"
                                  @click.native="handleUser(scope.row,scope.index)"
                                  size="small">角色成员
                </el-dropdown-item>

                <el-dropdown-item
                    size="small"
                    v-permission="'SYSTEM_ROLE_SELECT_URL'"
                    icon="el-icon-paperclip"
                    @click.native="handleRole(scope.row,scope.index)">功能权限
                </el-dropdown-item>

                <el-dropdown-item
                    size="small"
                    v-permission="'SYSTEM_DATASCOPE_LIST'"
                    icon="el-icon-s-data"
                    @click.native="handleData(scope.row,scope.index)">数据权限
                </el-dropdown-item>

            </template>

        </avue-crud>

        <el-drawer
            :title="`[${roleUserName}] 角色成员`"
            append-to-body
            size="1000px"
            :visible.sync="userBox">

            <basic-container>
                <avue-crud :option="optionUser"
                           :data="dataUser"
                           :page.sync="pageUser"
                           :table-loading="userLoading"
                           :search.sync="searchUser"
                           ref="tableUser"
                           @search-change="searchChangeUser"
                           @search-reset="searchResetUser"
                           @current-change="currentChangeUser"
                           @size-change="sizeChangeUser">

                    <template slot="menuLeft" slot-scope="{size}">
                        <el-button v-permission="'SYSTEM_ROLE_ADDUSER'" icon="el-icon-plus" type="primary" :size="size"
                                   @click.stop="roleUser()">添加
                        </el-button>
                        <el-button v-permission="'SYSTEM_ROLE_DELUSER'" icon="el-icon-delete" type="danger" :size="size"
                                   @click.stop="deleteUser()" :loading="deleteUserLoading">去除
                        </el-button>
                    </template>

                    <template slot-scope="{disabled,size}" slot="userTypeStrSearch">
                        <avue-select v-model="searchUser.userType_eq" placeholder="请选择用户类型" :disabled="disabled"
                                     :size="size" type="tree" :props="{label: 'name',value: 'code'}"
                                     :dic="userTypeList"></avue-select>
                    </template>
                    <template slot-scope="{disabled,size}" slot="orgNameSearch">
                        <avue-input-tree v-model="searchUser.orgId_eq" placeholder="请选择部门" :disabled="disabled"
                                         :size="size" type="tree" :props="{label: 'name',value: 'id'}"
                                         :dic="orgList"></avue-input-tree>
                    </template>

                </avue-crud>
            </basic-container>

        </el-drawer>

        <el-dialog custom-class="avue-dialog" class="avue-dialog"
                   v-dialogDrag
                   :close-on-click-modal="false"
                   title="添加成员"
                   top="20px"
                   append-to-body
                   :visible.sync="roleUserBox">

            <avue-crud :option="optionRoleUser"
                       :data="dataRoleUser"
                       :page="pageRoleUser"
                       :table-loading="roleUserLoading"
                       :search.sync="searchRoleUser"
                       ref="tableRoleUser"
                       @search-change="searchChangeRoleUser"
                       @search-reset="searchResetRoleUser"
                       @current-change="currentChangeRoleUser"
                       @size-change="sizeChangeRoleUser">

                <template slot-scope="{disabled,size}" slot="userTypeStrSearch">
                    <avue-select v-model="searchRoleUser.userType_eq" placeholder="请选择用户类型" :disabled="disabled"
                                 :size="size" type="tree" :props="{label: 'name',value: 'code'}"
                                 :dic="userTypeList"></avue-select>
                </template>
                <template slot-scope="{disabled,size}" slot="orgNameSearch">
                    <avue-input-tree v-model="searchRoleUser.orgId_eq" placeholder="请选择部门" :disabled="disabled"
                                     :size="size" type="tree" :props="{label: 'name',value: 'id'}"
                                     :dic="orgList"></avue-input-tree>
                </template>

            </avue-crud>

            <span slot="footer"
                  class="avue-dialog__footer">
        <el-button @click="roleUserBox = false">取 消</el-button>
        <el-button type="primary" :loading="addUserLoading" @click="addUser">确 定</el-button>
      </span>
        </el-dialog>

        <el-dialog custom-class="avue-dialog"
                   v-dialogDrag
                   :close-on-click-modal="false"
                   @close="functionClose"
                   :title="`[${menuTitle}] 配置功能权限`"
                   width="80%"
                   append-to-body
                   top="10px"
                   :visible.sync="box">

            <div class="block">
                <span class="demonstration">当前客户端:&nbsp;&nbsp;</span>
                <avue-select v-model="functionClientId"
                             label="当前客户端"
                             placeholder="请选择客户端"
                             :clearable="false"
                             class="el-input--small el-input--suffix"
                             type="tree"
                             :props="{label: 'name',value: 'id'}"
                             :dic="functionClientList"></avue-select>
            </div>

            <el-container>

                <el-aside width="200px">
                    <p class="el-dialog__title">顶部菜单</p>

                    <avue-tree :data="this.allTopMenu"
                               :option="{nodeKey: 'id',
                     border: true,
                     multiple:!boxDisabled,
                     filter:false,
                     menu:false,
                     props:
                      {
                        label:'name',
                        value:'id'
                      }}"
                               ref="topMenu"
                               :style="styleName"
                               @check-change="checkTopMenu"
                               @node-click="listLeftMenu">
                    </avue-tree>

                </el-aside>

                <el-aside style="width: 200px">
                    <p class="el-dialog__title">菜单</p>
                    <avue-tree :data="menuGrantList"
                               :option="{nodeKey: 'id',
                     defaultExpandAll:true,
                     border: true,
                     multiple:!boxDisabled,
                     filter:false,
                     menu:false,
                     props:
                      {
                        label:'functionName',
                        value:'id'
                      }}"
                               ref="treeMenu"
                               :style="styleName"
                               @check-change="checkChange"
                               @node-click="listFunction">
                    </avue-tree>
                </el-aside>

                <el-main>
                    <p class="el-dialog__title">按钮、接口</p>

                    <avue-crud ref="functionTable"
                               :data="functionList"
                               :option="optionFunction"
                               :table-loading="boxLoading"
                               @select="functionSelect"
                               @select-all="functionSelectAll">

                        <template slot="functionName" slot-scope="scope">
                            <el-popover
                                placement="right-end"
                                title="接口资源"
                                width="500"
                                :disabled="interfaceList.filter(f=>f.parentId === scope.row.id).length <= 0"
                                :close-delay="0"
                                @show="showInterface(scope.row)"
                                @after-enter="checkInterface(scope.row)"
                                @hide="hideInterface(scope.row)"
                                trigger="hover">

                                <el-table :ref="'interfaceTable'+scope.row.id"
                                          @selection-change="interfaceSelectionChange" row-key="id"
                                          :data="showInterfaceList">
                                    <el-table-column type="selection" width="55"></el-table-column>
                                    <el-table-column property="functionName" label="名称"
                                                     show-overflow-toolti></el-table-column>
                                    <el-table-column property="url" label="URL" show-overflow-tooltip></el-table-column>
                                </el-table>

                                <el-link slot="reference"
                                         :type="interfaceList.filter(f=>f.parentId === scope.row.id).length <= 0?'info':'primary'"
                                         :underline="false">{{ scope.row.functionName }}
                                </el-link>

                            </el-popover>
                        </template>

                        <template slot="functionType" slot-scope="scope">
                            <el-tag :type="scope.row.functionType===0?'warning':'success'">
                                {{ scope.row.functionType === 0 ? '按钮' : '接口' }}
                            </el-tag>
                        </template>

                    </avue-crud>
                </el-main>
            </el-container>

            <span slot="footer"
                  class="avue-dialog__footer">
        <el-button v-loading="boxDisabled" @click="box = false">取 消</el-button>
        <el-button v-loading="boxDisabled" v-permission="'SYSTEM_ROLE_UPDATEFUNCTION'" type="primary" @click="submit">确 定</el-button>
      </span>
        </el-dialog>

        <el-dialog custom-class="avue-dialog"
                   v-dialogDrag
                   :close-on-click-modal="false"
                   :title="`[${menuTitle}] 配置数据权限`"
                   width="80%"
                   append-to-body
                   top="10px"
                   :visible.sync="databox">

            <div class="block">
                <span class="demonstration">当前客户端&顶部菜单:&nbsp;&nbsp;</span>
                <avue-cascader v-model="dataClientId"
                               label="当前客户端"
                               placeholder="请选择客户端&顶部菜单"
                               :clearable="false"
                               class="el-input--small el-input--suffix"
                               popper-class="popper"
                               check-strictly
                               ref="dataCascader"
                               :props="{label: 'name', value: 'id', leaf: 'hasChildren'}"
                               :dic="dataClientList"></avue-cascader>
            </div>

            <el-container>
                <el-aside width="200px">
                    <p class="el-dialog__title">菜单</p>

                    <avue-tree :data="this.menuData"
                               :option="{nodeKey: 'id',
                     border: true,
                     filter:false,
                     menu:false,
                     defaultExpandAll:true,
                     props:
                      {
                        label:'functionName',
                        value:'id'
                      }}"
                               ref="treeData"
                               :style="styleName"
                               @node-click="listDataScope">
                    </avue-tree>


                </el-aside>
                <el-main>
                    <p class="el-dialog__title">数据权限</p>
                    <avue-crud ref="dataScopeTable"
                               :data="scopedList"
                               :option="optionScope"
                               :table-loading="boxDataLoading"
                               @selection-change="currentRowChange">

                        <template slot="allRole" slot-scope="scope">
                            <el-tag>{{ scope.row.params.allRole }}</el-tag>
                        </template>

                    </avue-crud>
                </el-main>
            </el-container>

            <span slot="footer"
                  class="avue-dialog__footer">
        <el-button v-loading="dataBoxDisabled" @click="databox = false">取 消</el-button>
        <el-button v-loading="dataBoxDisabled" v-permission="'SYSTEM_DATASCOPE_ROLE'" type="primary"
                   @click="submitDataScope">确 定</el-button>
      </span>
        </el-dialog>
    </basic-container>
</template>

<script>
import {menuTree} from '@/api/system/function';
import {
    addFunction,
    addRoleUser,
    deleteRoleUser,
    listButByMenu,
    listByMenuId,
    listByRole,
    listIdByRoleId,
    queryUrlIdByRole,
    roleDataScope
} from '@/api/system/roleTree'
import request from '@/router/axios';
import {treeAddDisabled, delItemById, addItemById, treeFindById} from '@/util/util'
import {validatenull} from "@/util/validate";
import func from "@/util/func";

export default window.$crudCommon({
    data() {
        return {
            heightCalc: 339,
            height: 0,
            functionClientId: '',
            functionClientList: [],
            dataClientId: '',
            dataClientList: [],
            oldEditForm: {},
            form: {},
            box: false,
            boxLoading: false,
            boxDataLoading: false,
            boxDisabled: false,
            dataBoxDisabled: false,
            databox: false,
            userBox: false,
            roleUserBox: false,
            roleUserName: '',
            dataIds: [],
            list: [],
            scopedList: [],
            menuGrantList: [],
            interfaceList: [],
            showInterfaceList: [],
            functionIds: [],
            menuData: [],
            userTypeList: [],
            orgList: [],
            functionList: [],
            optionFunction: {
                index: false,
                indexFixed: false,
                tree: true,
                treeProps: {
                    hasChildren: 'has'
                },
                defaultExpandAll: true,
                header: false,
                indexLabel: '序号',
                selection: true,
                selectionFixed: false,
                tip: true,
                searchShow: false,
                menu: false,
                border: true,
                columnBtn: false,
                addBtn: false,
                refreshBtn: false,
                align: 'center',
                height: 'auto',
                calcHeight: 140,
                column: [
                    {
                        label: "功能名称",
                        prop: "functionName",
                        align: 'left',
                        overHidden: true
                    },
                    {
                        label: "别名",
                        prop: "alias",
                        overHidden: true
                    },
                    {
                        label: "编码",
                        prop: "code",
                        overHidden: true
                    },
                    {
                        label: "路由",
                        prop: "url",
                        overHidden: true
                    },
                    {
                        label: "类型",
                        prop: "functionType",
                        slot: true
                    }
                ]
            },
            optionScope: {
                index: true,
                indexFixed: false,
                header: false,
                indexLabel: '序号',
                selection: true,
                selectionFixed: false,
                tip: true,
                searchShow: false,
                menu: false,
                border: true,
                columnBtn: false,
                addBtn: false,
                refreshBtn: false,
                align: 'center',
                height: 'auto',
                calcHeight: 140,
                rowKey: 'id',
                column: [
                    {
                        label: "权限编号",
                        prop: "scopeCode"
                    },
                    {
                        label: "数据权限名称",
                        prop: "scopeName"
                    },
                    {
                        label: "是否所有角色都执行",
                        prop: "allRole",
                        type: "switch",
                        slot: true,
                        dicUrl: window.urllist.dictUrl + 'YN01',
                        dataType: 'number',
                        props: {
                            label: "name",
                            value: "code"
                        }
                    }
                ]
            },
            optionUser: {
                index: true,
                indexLabel: '序号',
                selection: true,
                tip: true,
                searchShow: true,
                menu: false,
                border: true,
                addBtnText: "添加",
                columnBtn: false,
                addBtn: false,
                refreshBtn: false,
                align: 'center',
                rowKey: 'id',
                reserveSelection: true,
                maxHeight: 800,
                searchMenuSpan: 8,
                searchIndex: 3,
                searchIcon: true,
                dialogClickModal: false,
                dialogDrag: true,
                column: [
                    {
                        label: "用户名",
                        prop: "loginId",
                        search: true
                    },
                    {
                        label: '用户昵称',
                        prop: 'nickName',
                        search: true
                    },
                    {
                        label: "部门",
                        prop: "orgName",
                        overHidden: true,
                        searchslot: true,
                        search: true
                    },
                    {
                        label: "用户类型",
                        prop: "userTypeStr",
                        searchslot: true,
                        search: true
                    },
                    {
                        label: "用户姓名",
                        prop: "userName",
                        overHidden: true,
                        search: true
                    },
                    {
                        label: "电话",
                        prop: "telephone",
                        overHidden: true
                    }
                ]
            },
            dataUser: [],
            pageUser: {
                pageSize: 10,
                currentPage: 1,
                total: 0
            },
            searchUser: {},
            userLoading: true,
            selectTenantCode: '',
            roleId: '',
            optionRoleUser: {
                index: true,
                indexLabel: '序号',
                selection: true,
                tip: true,
                searchShow: true,
                menu: false,
                border: true,
                addBtnText: "添加",
                columnBtn: false,
                addBtn: false,
                refreshBtn: false,
                align: 'center',
                maxHeight: 450,
                rowKey: 'id',
                reserveSelection: true,
                searchMenuSpan: 8,
                searchIndex: 3,
                searchIcon: true,
                dialogClickModal: false,
                dialogDrag: true,
                column: [
                    {
                        label: "用户名",
                        prop: "loginId",
                        search: true
                    },
                    {
                        label: '用户昵称',
                        prop: 'nickName',
                        search: true
                    },
                    {
                        label: "部门",
                        prop: "orgName",
                        overHidden: true,
                        searchslot: true,
                        search: true
                    },
                    {
                        label: "用户类型",
                        prop: "userTypeStr",
                        searchslot: true,
                        search: true
                    },
                    {
                        label: "用户姓名",
                        prop: "userName",
                        overHidden: true,
                        search: true
                    },
                    {
                        label: "电话",
                        prop: "telephone",
                        overHidden: true
                    }
                ]
            },
            dataRoleUser: [],
            pageRoleUser: {
                pageSize: 10,
                currentPage: 1,
                total: 0
            },
            searchRoleUser: {},
            roleUserLoading: true,
            addUserLoading: false,
            deleteUserLoading: false,
            isChange: false,
            isDataChange: true,
            allTopMenu: [],
            topMenuIds: [],
            menuTitle: ''
        }
    },
    created() {
        request.get(window.urllist.dictUrl + 'USER_TYPE').then((res) => {
            this.userTypeList = res.data.data;
        });
    },
    computed: {
        styleName() {
            return {
                height: this.height + 'px'
            }
        }
    },
    mounted() {
        this.height = document.documentElement.clientHeight - this.heightCalc;
    },
    watch: {
        "form.tenantCode"(tenantCode) {
            if (!this.validatenull(tenantCode)) {
                this.api['list']({"tenantCode": tenantCode}).then((res) => {
                    this.findObject(this.$refs.crud.option.column, 'parentId').dicData = treeAddDisabled(res.data.data || [], this.form.id);
                });
            }
        },
        'functionClientId'() {
            this.menuGrantList = [];
            this.allTopMenu = [];
            this.interfaceList = [];
            this.functionList = [];

            // 查询所有接口 查询所有菜单 查询顶部菜单
            if (this.functionClientId){
                Promise.all([this.api['listInterface'](this.functionClientId), menuTree({clientId: this.functionClientId}), this.api['listAllMenu'](this.functionClientId)]).then(
                    result => {
                        this.interfaceList = result[0].data.data;
                        this.menuGrantList = result[1].data.data;
                        this.allTopMenu = result[2].data.data;

                        // 给顶部菜单赋值
                        this.selectTopMenu();
                        // 给菜单赋值
                        this.selectLeftMenu();
                        // 加载按钮
                        this.listFunction();
                    }
                )

            }

        },
        'dataClientId'() {
            // todo 这行不起作用
            this.$refs.dataCascader.dropDownVisible = false;

            //查询菜单
            let cid = this.dataClientId.split(",")[0];
            let mid = this.dataClientId.split(",")[1] || '';

            menuTree({clientId: cid, topMenuId: mid}).then(res => {
                this.menuData = res.data.data;
            });

            this.scopedList = [];
        }
    },
    methods: {
        currentRowChange(selection) {
            if (this.isDataChange) {
                this.scopedList.forEach(e => {
                    const index = this.dataIds.indexOf(e.id);
                    if (index >= 0) {
                        this.dataIds.splice(index, 1);
                    }
                });

                selection.forEach(e => {
                    if (!this.dataIds.includes(e.id)) {
                        this.dataIds.push(e.id)
                    }
                });
            }
        },
        listDataScope(data) {
            this.boxDataLoading = true;
            listByMenuId({
                menuId: data.id
            }).then(res => {
                this.boxDataLoading = false;
                this.scopedList = res.data.data;
                this.isDataChange = false;

                this.$nextTick(() => {
                    const selectDataIds = [];
                    this.dataIds.forEach(ele => {
                        this.scopedList.forEach(e => {
                            if (ele === e.id) {
                                selectDataIds.push(e)
                            }
                        })
                    });

                    this.$refs.dataScopeTable.toggleSelection(selectDataIds);
                    this.isDataChange = true;
                });

            });

        },
        submitDataScope() {
            this.dataBoxDisabled = true;
            roleDataScope({
                roleId: this.roleId,
                dataIds: this.dataIds.join(',')
            }).then(() => {
                this.dataBoxDisabled = false;
                this.databox = false;
                this.$message({
                    type: "success",
                    message: "操作成功"
                });
            }).catch(() => {
                this.dataBoxDisabled = false;
            });
        },
        checkTopMenu(data, is) {
            const index = this.topMenuIds.indexOf(data.id);
            if (is && index < 0) {
                this.topMenuIds.push(data.id);
            }
            if (!is && index >= 0) {
                this.topMenuIds.splice(index, 1);
            }
        },
        checkChange(node) {
            this.delAllFunctions(this.menuGrantList);
            this.functionIds.push(...this.$refs.treeMenu.getCheckedKeys(), ...this.$refs.treeMenu.getHalfCheckedKeys());

            // 设置当前显示的table，如果所属菜单选中那么接口都要选中。如果未选中那么接口也要自动去掉选中
            this.functionList.filter(f => f.parentId === node.id).filter(f => f.functionType === 2).forEach(f => {
                if (this.functionIds.includes(f.parentId)) {
                    this.$refs.functionTable.toggleRowSelection(f, true);
                } else {
                    this.$refs.functionTable.toggleRowSelection(f, false);
                }
            });

            // 设置最终选中的值
            this.interfaceList.filter(f => f.parentId === node.id).forEach(f => {
                if (this.functionIds.includes(f.parentId) && !this.functionIds.includes(f.id)) {
                    this.functionIds.push(f.id);
                } else if (!this.functionIds.includes(f.parentId) && this.functionIds.includes(f.id)) {
                    this.functionIds.splice(this.functionIds.indexOf(f.id), 1);
                }
            });
        },
        delAllFunctions(list) {
            list.forEach(e => {

                if (e.hasChildren) {
                    this.delAllFunctions(e.children);
                }

                const index = this.functionIds.indexOf(e.id);
                if (index >= 0) {
                    this.functionIds.splice(index, 1);
                }

            });
        },
        hideInterface() {
            this.showInterfaceList = [];
            this.isShowInterface = false;
        },
        showInterface(row) {
            this.showInterfaceList = this.interfaceList.filter(f => row.id === f.parentId);
        },
        checkInterface(row) {
            this.showInterfaceList.forEach(face => {
                if (this.functionIds.includes(face.id)) {
                    this.$refs['interfaceTable' + row.id].toggleRowSelection(face, true);
                }
            });

            this.isShowInterface = true;
        },
        interfaceSelectionChange(selected) {
            if (this.isShowInterface) {
                this.showInterfaceList.forEach(i => {
                    const index = this.functionIds.indexOf(i.id);
                    if (index >= 0) {
                        this.functionIds.splice(index, 1);
                    }
                });

                selected.map(s => s.id).forEach(id => {
                    if (!this.functionIds.includes(id)) {
                        this.functionIds.push(id);
                    }
                });
            }
        },
        listChildren(selection, isCheck) {
            selection.forEach(e => {
                this.$refs.functionTable.toggleRowSelection(e, isCheck);
                if (e.hasChildren) {
                    this.listChildren(e.children, isCheck);
                }

                if (isCheck) {
                    if (!this.functionIds.includes(e.id)) {
                        this.functionIds.push(e.id);
                    }

                    //设置下面得接口资源自动选中
                    this.interfaceList.filter(f => f.parentId === e.id).forEach(f => {
                        if (!this.functionIds.includes(f.id)) {
                            this.functionIds.push(f.id);
                        }
                    })
                } else {
                    const index = this.functionIds.indexOf(e.id)
                    if (index >= 0) {
                        this.functionIds.splice(index, 1);
                    }
                    //删除下面得接口资源
                    this.interfaceList.filter(f => f.parentId === e.id).forEach(f => {
                        const interIndex = this.functionIds.indexOf(f.id);
                        if (interIndex >= 0) {
                            this.functionIds.splice(interIndex, 1);
                        }
                    })
                }

            });
        },
        functionSelect(selection, row) {
            const isCheck = selection.indexOf(row) >= 0;
            if (row.hasChildren) {
                this.listChildren(row.children, isCheck);
            }

            const checkAncestors = (row) => {
                const parent = treeFindById(this.functionList, row.parentId, "id");
                if (parent !== undefined && isCheck) {
                    this.$refs.functionTable.toggleRowSelection(parent, isCheck);

                    if (!this.functionIds.includes(parent.id)) {
                        this.functionIds.push(parent.id);


                        //设置下面得接口资源自动选中
                        this.interfaceList.filter(f => f.parentId === parent.id).forEach(f => {
                            if (!this.functionIds.includes(f.id)) {
                                this.functionIds.push(f.id);
                            }
                        })

                    }

                    checkAncestors(parent);
                }
            }
            checkAncestors(row);

            if (isCheck) {
                if (!this.functionIds.includes(row.id)) {
                    this.functionIds.push(row.id);
                }
                //设置下面得接口资源自动选中
                this.interfaceList.filter(f => f.parentId === row.id).forEach(f => {
                    if (!this.functionIds.includes(f.id)) {
                        this.functionIds.push(f.id);
                    }
                })
            } else {
                const index = this.functionIds.indexOf(row.id)
                if (index >= 0) {
                    this.functionIds.splice(index, 1);
                }
                //删除下面得接口资源
                this.interfaceList.filter(f => f.parentId === row.id).forEach(f => {
                    const interIndex = this.functionIds.indexOf(f.id);
                    if (interIndex >= 0) {
                        this.functionIds.splice(interIndex, 1);
                    }
                })
            }
        },
        functionSelectAll(selection) {
            let parentId = '-1';
            if (this.functionList.length > 0) {
                parentId = this.functionList[0].parentId;

                const topSel = selection.filter(sel => sel.parentId === parentId);
                const isCheck = topSel.length === this.functionList.length;

                this.functionList.forEach(sel => {
                    if (sel.hasChildren) {
                        this.listChildren(sel.children, isCheck);
                    }

                    const index = this.functionIds.indexOf(sel.id);

                    if (isCheck) {
                        //设置下面得接口资源自动选中
                        this.interfaceList.filter(f => f.parentId === sel.id).forEach(f => {
                            if (!this.functionIds.includes(f.id)) {
                                this.functionIds.push(f.id);
                            }
                        })

                        if (index < 0) {
                            this.functionIds.push(sel.id);
                        }
                    } else {
                        //删除下面得接口资源
                        this.interfaceList.filter(f => f.parentId === sel.id).forEach(f => {
                            const interIndex = this.functionIds.indexOf(f.id);
                            if (interIndex >= 0) {
                                this.functionIds.splice(interIndex, 1);
                            }
                        })

                        if (index >= 0) {
                            this.functionIds.splice(index, 1);
                        }
                    }

                })
            }
        },
        listFunction(data = {}) {
            this.boxLoading = true;
            this.functionList = [];
            listButByMenu({id: data.id, clientId: this.functionClientId}).then((res) => {
                this.boxLoading = false
                this.isChange = false;// 标记这时不要去更新选中的数据
                this.functionList = res.data.data;
                this.functionList.push(...this.interfaceList.filter(f => f.parentId === (data.id || -1)));

                this.$nextTick(() => {

                    const selectFunction = [];
                    this.functionIds.forEach(ele => {

                        const addIds = (functionList) => {
                            functionList.forEach(e => {
                                if (ele === e.id) {
                                    selectFunction.push(e);
                                }

                                if (e.hasChildren) {
                                    addIds(e.children);
                                }
                            })
                        };
                        addIds(this.functionList);

                    });

                    this.$refs.functionTable.toggleSelection(selectFunction);
                    this.isChange = true;
                });
            });
        },
        listLeftMenu(data = {}) {
            menuTree({clientId: this.functionClientId, topMenuId: data.id}).then(res => {
                this.menuGrantList = res.data.data;
                this.selectLeftMenu();
            });
        },
        /**
         * 选中左侧菜单
         */
        selectLeftMenu() {
            let result = [];
            const callback = (tree) => {
                tree.forEach(e => {

                    if (e.hasChildren) {
                        callback(e.children);
                    } else {
                        if (this.functionIds.findIndex(item => item === e.id) !== -1) result.push(e.id);
                    }

                })
            };
            callback(this.menuGrantList);

            this.$refs.treeMenu.setCheckedKeys(result);
        },
        /**
         * 给顶部菜单赋值
         */
        selectTopMenu() {
            this.$refs.topMenu.setCheckedKeys(this.topMenuIds);
        },
        submit() {
            this.boxDisabled = true
            addFunction({
                roleId: this.roleId,
                functionIds: this.functionIds,
                topMenuIds: this.topMenuIds
            }).then(() => {
                this.boxDisabled = false;
                this.box = false;
                this.$message({
                    type: "success",
                    message: "操作成功"
                });
            }).catch(() => {
                this.boxDisabled = false;
            });
        },
        handleData(row) {
            this.menuTitle = row.name;
            this.api['listClientMenu']().then(clientRes => {

                if (validatenull(clientRes.data.data)) {
                    this.$message.error('请先新建客户端');
                    return;
                }

                this.dataClientList = clientRes.data.data;
                this.dataClientId = clientRes.data.data[0].id;

                //加载数据
                this.roleId = row.id;
                this.scopedList = [];

                //查询菜单
                menuTree({clientId: this.dataClientId}).then(res => {
                    this.menuData = res.data.data;
                    this.databox = true;
                });

                //查询该角色所拥有的数据权限
                listIdByRoleId({roleIds: row.id}).then(result => {
                    this.dataIds = result.data.data;
                });
            });
        },
        functionClose(){
            this.functionClientId = '';
        },
        handleRole(row) {

            this.menuTitle = row.name;
            this.api['clientList']().then(clientRes => {

                if (validatenull(clientRes.data.data)) {
                    this.$message.error('请先新建客户端');
                    return;
                }

                this.functionClientList = clientRes.data.data;

                //加载数据
                this.roleId = row.id;
                this.functionIds = [];
                this.topMenuIds = [];

                Promise.all([queryUrlIdByRole({roleIds: row.id}), this.api['topMenuId'](row.id)]).then(
                    result => {
                        this.functionIds = result[0].data.data;
                        this.topMenuIds = result[1].data.data;

                        this.functionClientId = clientRes.data.data[0].id;
                        this.box = true;
                    }
                )
            });
        },
        searchChangeUser(params, done) {
            this.pageUser.currentPage = 1;
            this.onLoadUser(this.pageUser, params);
            done();
        },
        searchResetUser() {
            this.pageUser.currentPage = 1;
            this.onLoadUser(this.pageUser);
        },
        currentChangeUser(currentPage) {
            this.pageUser.currentPage = currentPage;
            this.onLoadUser(this.pageUser, this.searchUser);
        },
        sizeChangeUser(pageSize) {
            this.pageUser.pageSize = pageSize;
            this.pageUser.currentPage = 1;
            this.onLoadUser(this.pageUser, this.searchUser);
        },
        handleUser(row) {
            this.selectTenantCode = row.tenantCode;
            this.roleId = row.id;
            this.roleUserName = row.name
            this.pageUser = {
                pageSize: 10,
                currentPage: 1,
                total: 0
            };
            this.searchUser = {};
            this.onLoadUser(this.pageUser);

            if (this.$refs.tableUser) {
                this.$nextTick(() => {
                    this.$refs.tableUser.searchReset();
                    this.$refs.tableUser.selectClear();
                })
            }
            this.userBox = true;

            let url = window.urllist.system + '/core/org/tree';
            if (this.$store.getters.isShowTenantCode) {
                url = url + '?tenantCode=' + row.tenantCode;
            }

            request.get(url).then((res) => {
                this.orgList = res.data.data;
            });
        },
        onLoadUser(page, params = {}) {
            this.userLoading = true;
            const values = {
                ...params,
                isEq: 'Y',
                pageNum: page.currentPage,
                pageSize: page.pageSize
            }
            this.listRole(values).then(res => {
                const data = res.data.data;
                this.pageUser.total = data.total;
                this.dataUser = data.list;
                this.userLoading = false;
            });
        },
        listRole(params = {}) {
            const values = {
                ...params,
                roleId: this.roleId
            }
            if (this.$store.getters.isShowTenantCode) {
                values.tenantCode_eq = this.selectTenantCode;
            }
            return listByRole(values);
        },
        roleUser() {
            this.pageRoleUser = {
                pageSize: 10,
                currentPage: 1,
                total: 0
            };
            this.searchRoleUser = {};
            this.onLoadRoleUser(this.pageRoleUser);

            if (this.$refs.tableRoleUser) {
                this.$nextTick(() => {
                    this.$refs.tableRoleUser.searchReset();
                    this.$refs.tableRoleUser.selectClear();
                })
            }

            this.roleUserBox = true;
        },
        onLoadRoleUser(page, params = {}) {
            this.roleUserLoading = true;

            const values = {
                ...params,
                isEq: 'N',
                pageNum: page.currentPage,
                pageSize: page.pageSize
            }
            this.listRole(values).then(res => {
                const data = res.data.data;
                this.pageRoleUser.total = data.total;
                this.dataRoleUser = data.list;
                this.roleUserLoading = false;
            });
        },
        searchChangeRoleUser(params, done) {
            this.pageRoleUser.currentPage = 1;
            this.onLoadRoleUser(this.pageRoleUser, params);
            done();
        },
        searchResetRoleUser() {
            this.pageRoleUser.currentPage = 1;
            this.onLoadRoleUser(this.pageRoleUser);
        },
        currentChangeRoleUser(currentPage) {
            this.pageRoleUser.currentPage = currentPage;
            this.onLoadRoleUser(this.pageRoleUser, this.searchRoleUser);
        },
        sizeChangeRoleUser(pageSize) {
            this.pageRoleUser.pageSize = pageSize;
            this.pageRoleUser.currentPage = 1;
            this.onLoadRoleUser(this.pageRoleUser, this.searchRoleUser);
        },
        addUser() {

            let ids = [];
            this.$refs.tableRoleUser.tableSelect.forEach(ele => {
                ids.push(ele.id);
            });

            if (ids.length <= 0) {
                this.$message.warning('至少选择一条数据');
                return;
            }

            this.addUserLoading = true;

            addRoleUser({roleId: this.roleId, userIds: ids.join(",")}).then((res) => {
                if (res.data.status) {
                    this.onLoadUser(this.pageUser, this.searchUser);
                    this.roleUserBox = false;
                    this.$message.success('添加成功');
                } else {
                    this.$message.error(res.data.message);
                }
                this.addUserLoading = false;
            }).catch(() => {
                this.addUserLoading = false;
            });
        },
        deleteUser() {
            let ids = [];
            this.$refs.tableUser.tableSelect.forEach(ele => {
                ids.push(ele.id);
            });

            if (ids.length <= 0) {
                this.$message.warning('至少选择一条数据');
                return;
            }

            this.$confirm(`确定去除所选用户吗？`, '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {

                this.deleteUserLoading = true;

                deleteRoleUser({roleId: this.roleId, userIds: ids.join(",")}).then((res) => {
                    if (res.data.status) {
                        this.pageUser.currentPage = 1;
                        this.onLoadUser(this.pageUser, this.searchUser);
                        this.$refs.tableUser.selectClear();
                        this.$message.success('去除成功');
                    } else {
                        this.$message.error(res.data.message);
                    }
                    this.deleteUserLoading = false;
                }).catch(() => {
                    this.deleteUserLoading = false;
                });

            })

        },
        beforeOpen(done, type) {
            if (["add"].includes(type)) {
                this.form.tenantCode = this.$store.getters.tenantCode;
            }
            if (["edit"].includes(type)) {
                this.oldEditForm = this.form;
            }
            done();
        },
        addAfter(row, done, data) {
            done(Object.assign(row, {
                id: data.data,
                children: []
            }));
            this.$message.success('新增成功');
            this.$refs.crud.updateDic('parentId');
        },
        updateAfter(row, done) {
            if (row.parentId === undefined) {
                row.parentId = '-1';
            }
            const data = delItemById(this.$refs.crud.data, row.id);

            done(row);
            this.$message.success('修改成功');
            this.$refs.crud.updateDic('parentId');

            if (data) {
                //avue更新后会丢失箭头，所以我这里不管改没改上级ID，都去修改下；
                const index = this.oldEditForm.parentId !== row.parentId ? 0 : data.index;
                addItemById(this.$refs.crud.data, Object.assign(data.data, row), index);
            }
        },
        delAfter(row, done) {
            done(row);
            this.$message.success('删除成功');
            this.$refs.crud.updateDic('parentId');
        },
        delsAfter(ids) {
            func.split(ids).forEach(id => {
                delItemById(this.$refs.crud.data, id);
            })
            this.$message.success('删除成功');
            this.$refs.crud.updateDic('parentId');
        }
    }
}, {
    name: '/system/roleTree',
    res: (data) => {
        return {
            data: data.data
        }
    },
    crudPage: false
})
</script>

<style lang="scss">
.chilentTable .avue-crud > .avue-crud__menu {
    display: none !important;
}

.avue-tree__content {
    height: calc(100% - 15px);
}

.el-cascader {
    width: 250px;
    line-height: 32px !important;
}

.popper .el-cascader-panel .el-radio {
    width: 100%;
    height: 100%;
    z-index: 10;
    position: absolute;
    top: 0px;
    right: 0px;
}

.popper .el-cascader-panel .el-checkbox {
    width: 100%;
    height: 100%;
    z-index: 10;
    position: absolute;
    top: 0px;
    right: 0px;
}

.popper .el-cascader-panel .el-radio__input {
    margin-top: 10px;
    margin-left: 8px;
}

.popper .el-cascader-panel .el-checkbox__input {
    margin-top: 2px;
    margin-left: 8px;
}

.popper .el-cascader-panel .el-cascader-node__postfix {
    top: 10px;
}
</style>
